import { spawn } from 'child_process';
import fs from 'fs';
import path from 'path';
import { afterBuildFinish, beforeStartBuild } from '../build-custom/BuildCustom';
import PackUtil from '../utils/PackUtil';
import { ChannelInfo } from './PlatformConfig';
export class BasePlatform {
    public configData: any;
    public channelInfo: ChannelInfo = null!;
    public enginePath: string = "";
    public curPackChannel: string = "";
    public projectDir: string = "";
    public isDebug: boolean = false;
    public version: string = '1.0.0';//版本名称
    public appVerCode: number = 1;//app版本号，小游戏不需要
    public outputPath: string = '';
    public desc: string | null = null;
    public bmsName: string = "";
    public constructor() {
    }
    public init(options: {
        configData: any,
        channel: string,
        projectDir: string,
        isDebug?: boolean,
        forceVersion?: string,
        desc?: string,
    }) {
        this.configData = options.configData;
        this.enginePath = options.configData.enginePath;
        this.projectDir = options.projectDir;
        this.curPackChannel = options.channel;
        this.channelInfo = this.configData.platforms[this.curPackChannel];
        let outputpath = this.configData.outputDir;
        this.desc = options.desc!;
        this.isDebug = options.isDebug!;
        this.outputPath = path.join(outputpath, this.channelInfo.buildPath);
        PackUtil.mkdirSync(this.outputPath);//没有对应输出目录则创建目录
        if (options.forceVersion) {
            this.version = options.forceVersion;
        } else {
            this.checkNewVersion();
        }
        console.log("current is debug? ", this.isDebug);
    }
    public async startBuild() {
        let channelInfo = this.configData.platforms[this.curPackChannel];
        if (!channelInfo) {
            console.error(`current channel ${this.curPackChannel} config info does't exits, please confirm`);
            return;
        }
        //开始构建前
        await this.beforeStartBuild();
        let boo = true;
        //@ts-ignore
        if (!global.isSkipBuild) {
             boo = await this.build();
        }
        if (boo) {
            //构建完成后
            await this.afterBuildFinish();
        }
    }

    public async build(): Promise<boolean> {
        return new Promise<boolean>((resolve, reject) => {
            let configData = this.configData;
            let channelInfo = this.channelInfo;
            let buildPath = this.outputPath;
            //构建信息
            let buildInfo = `"title=${configData.title};platform=${channelInfo.platform};buildPath=${buildPath};debug=false;md5Cache=${channelInfo.md5Cache};`;
            if(channelInfo.previewHeight){
                buildInfo = `${buildInfo}previewWidth=${channelInfo.previewWidth};previewHeight=${channelInfo.previewHeight};`
            }
            if(channelInfo.sourceMaps){
                buildInfo = `${buildInfo}sourceMaps=true;`;
            }
            buildInfo = `${buildInfo}"`;
            try {
                console.log("building...");
                let sp = spawn(`${this.enginePath}`, ["--path", `${this.projectDir}`, "--build", `${buildInfo}`]);
                sp.stdout.setEncoding('utf8');
                sp.stdout.on('data', (data) => {
                    console.log(data.toString());
                });
                sp.stderr.on('data', (data) => {
                    console.log(data.toString());
                })
                sp.on('exit', (code, sign) => {
                    if (code == 0) {
                        console.log(`build finish ${this.curPackChannel}`);
                        resolve(true);
                    } else {
                        throw Error();
                    }
                });
                console.log("output path=", buildPath);
            } catch (error) {
                console.log(`build failed ${this.curPackChannel}:${error}`);
                reject(false);
            }
        });
    }

    public async beforeStartBuild() {
        let channelInfo = this.configData.platforms[this.curPackChannel];
        return new Promise<void>((resolve, reject) => {
            beforeStartBuild({ channel: this.curPackChannel, platformsInfo: channelInfo, projectDir: this.projectDir, isDebug: this.isDebug, bmsName:this.bmsName}, () => {
                resolve();
            })
        });
    }

    public async afterBuildFinish() {
        let channelInfo = this.configData.platforms[this.curPackChannel];
        return new Promise<void>((resolve, reject) => {
            afterBuildFinish({ platform: this }, () => {
                resolve();
            })
        });
    }

    public checkNewVersion() {
        let configVersion = this.channelInfo.version;//配置中的版本
        this.version = configVersion;
        //获取备份中的版本号 如果有
        const backPath = path.join(this.outputPath, 'pack.back.json');
        if (fs.existsSync(backPath)) {
            let backData: Object = JSON.parse(fs.readFileSync(backPath, { encoding: 'utf8' }));
            //@ts-ignore
            let backVersion: string = backData[this.curPackChannel];
            if (backVersion) {
                if (PackUtil.compareVersion(configVersion, backVersion) <= 0) {
                    this.version = PackUtil.versionUp(backVersion);
                }
            }
        }
    }

    public saveBackUpConfig() {
        let backData = {};
        //@ts-ignore
        backData[this.curPackChannel] = this.version;
        const backPath = path.join(this.outputPath, 'pack.back.json');
        if (fs.existsSync(backPath)) {
            fs.readFileSync(backPath, { encoding: 'utf8' });
            backData = JSON.parse(fs.readFileSync(backPath, { encoding: 'utf8' }));
            //@ts-ignore
            backData[this.curPackChannel] = this.version;
        }
        fs.writeFileSync(backPath, JSON.stringify(backData, null, "\t"), { encoding: 'utf8' });
    }
}